home *** CD-ROM | disk | FTP | other *** search
- Path: news.compuserve.com!newsmaster
- From: RossBoylan@aol.com (Ross Boylan)
- Newsgroups: comp.lang.c++,comp.os.ms-windows.programmer.misc
- Subject: Re: Virtual function question (summary of answers)
- Date: Tue, 09 Apr 1996 19:22:45 GMT
- Organization: CompuServe Incorporated
- Message-ID: <4ked7o$8g3@dub-news-svc-1.compuserve.com>
- References: <4jp6e9$ou5@dub-news-svc-1.compuserve.com>
- NNTP-Posting-Host: ad06-115.compuserve.com
- X-Newsreader: Forte Free Agent 1.0.82
-
- Problem: To define the comparison operators <, <=, >, ==, etc in
- terms of one or two primitives (< and maybe ==), so that all classes
- for which the comparisons make sense only require definition of the
- primitives.
-
- Solutions
- 1) The best solution I've seen is in the Standard Template library,
- e.g. (from function.h):
- template <class T>
- inline bool operator>=(const T& x, const T& y) {
- return !(x < y);
- }
-
- My original problem statement used member functions, but the symmetric
- free-standing functions are more appropriate to the comparison
- operators.
-
- 2) The remaining solutions use member functions (Borland's library
- apparently does this) and create bogus functions which take abstract
- classes as arguments. In the following, RBMagnitude::operator< is not
- virtual, so subclasses do not need to override it (they ignore it
- instead).
-
- class RBMagnitude {
- bool operator <(RBMagnitude& x) const
- {throw "Subclasses should override"; return 1;};
- // the throw is optional
- int operator >(RBMagnitude& x) { return x<*this;};
- //etc
- };
-
- class Number : public RBMagnitude {
- private:
- double myNumber;
- public:
- virtual bool operator<(Number& x) const
- {return myNumber < x.myNumber;}
- };
-
-
- 3) Several people suggested casting down as a possibility:
- class RBMagnitude {
- virtual bool operator <(RBMagnitude& x) const = 0;
- int operator >(RBMagnitude& x) { return x<*this;};
- //etc
- };
-
- class Number : public RBMagnitude {
- private:
- double myNumber;
- public:
- virtual bool operator<(RBMagnitude& x) const
- {return myNumber < ((Number&) x).myNumber;}
- // we could dynamically test the class of x if we were being careful
- };
-
- If the class is CObject derived we could have code like
- { if (x.IsKindOf(RUNTIME_CLASS(Number))
- return n < /* x might need casting?? */x.n;
- else return 0; /* or throw exception*/ }
-
- 4) My original problem defined all RBMagnitude operators as virtual.
- I have some potential subclasses which redefine all the inequality
- operators. However, the gain in computing comparisons directly may be
- offset by the overhead of virtual functions, and it is probably
- clearner not to use virtual functions.
-
- 5) Scott Meyer's new book, More Effective C++, has some material in
- item 33 which may be relevant (I haven't had a chance to look at it
- yet).
-
- Thanks to
- pab@maui.com (Paul A. Billings)
- William E. Kempf mailto:wekempf@marlton.1dc.com (work)
- Oliver Enseling e-mail: oliver@skypoint.com
- Maruthi NetQuest
- Saul Rosenberg rosenberg@decus.org
-
- Here's the original post, for reference.
- >I am trying to define, a la Smalltalk, a mix-in which defines the
- >various comparison operators in terms of one fundamental operator, <.
-
-
- >typedef int bool;
- >class RBMagnitude {
- >public:
- >//subclass should redefine < with appropriate types
- > virtual bool operator<(const RBMagnitude&) const= 0;
- > virtual bool operator>(const RBMagnitude& x) const {return *this <
- >x;};
- >// and many more
- >};
-
- >class A : public RBMagnitude {
- >public:
- > virtual bool operator<(const A& a) const {return (this->n < a.n);};
- >private:
- > int n;
- >};
-
-
- >class A test;
-
- >This fails in MSVC++ 4.0 with the error that A is virtual because the
- >operator<(const RBMagnitude&) is not defined.
- >It looks to me as if this is because the operator< for A has a
- >different type signature (it uses an A rather than an RBMagnitude).
- >If so, the problem is the language definition, not Microsoft's
- >implementation.
-
- >1) Is this interpretation correct? [yes, it is]
- >2) Is there any way around this problem? Commenting out the
- >definition of RBMagnitude::operator< doesn't work, because
- >RBMagnitude::operator> requires it. I suppose I could define a bogus
- >operator< which throws an exception, but this seems awkward (in
- >particular, if A and B are both RBMagnitudes and I ask A<B, I fail at
- >run time rather than compile time).
-
- >I would appreciate e-mail; I'll summarize here.
-
-
-